﻿
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using Tauren.File.DLL.FileDLL;
using Tauren.File.DLL.FileIODLL;
using Tauren.File.DLL.Resouces;
using Tauren.File.Entity.Config;
using Tauren.File.Entity.Enum;
using Tauren.File.Entity.Global;
using Tauren.File.Entity.Model;
using Tauren.File.Infrastructure.Common;
using Tauren.File.Infrastructure.Globals;

namespace Tauren.File.Service.FileVersionBLL
{
    public class FileVersionService : Base.BaseService, IFileVersionService
    {
        private IFileBusiness business;
        public IFileIOBusiness IOBusiness { get; set; }
        private FilePath filePath;
        public FileVersionService(IFileBusiness baseDLL, IConnectionBLLBase connectionBLL, IConfiguration configuration, IMenuResourcesBusiness resourcesBusiness) : base(baseDLL, connectionBLL, resourcesBusiness)
        {
            business = baseDLL;
            ///获取配置文件中的数据
            filePath = configuration.Get<ApiVersionsConfig>().FilePath;
        }

        /// <summary>
        /// 获取所有的历史信息
        /// </summary>
        /// <param name="fileid"></param>
        /// <returns></returns>
        public IResponseMessage RefreshHistory(long fileid)
        {
            ///获取该文件的所有版本
            List<FilesVersion> versions = business.GetVersionsByFileId(fileid: fileid);
            ///获取文件
            Files file = business.Get<Files>(fileid);
            return RefreshHistory(file, versions).OnSucceed();
        }

        /// <summary>
        /// 设置历史
        /// </summary>
        /// <param name="fileid"></param>
        /// <param name="version"></param>
        /// <returns></returns>
        public IResponseMessage SetHistoryData(long fileid, long version)
        {  ///获取该文件的所有版本
            List<FilesVersion> versions = business.GetVersionsByFileId(fileid: fileid);
            ///获取文件
            Files file = business.Get<Files>(fileid);
            return SetHistoryData(file, versions, version).OnSucceed();
        }
         

        /// <summary>
        /// 获取文件配置信息
        /// </summary>
        /// <param name="editType"></param>
        /// <param name="systemType"></param>
        /// <param name="fileid"></param>
        /// <returns></returns>
        public IResponseMessage Config(int editType, int systemType, int fileid)
        {
            ///获取文件
            Files files = business.Get<Files>(id: fileid);
            ///获取编辑模式
            EditType eType = (EditType)editType;
            ///获取系统
            SystemType system = (SystemType)systemType;
            List<FilesVersion> versions = business.All<FilesVersion>();
            FilesVersion version = null;
            if (versions.Any())
            {
                version = versions.FirstOrDefault(o => o.Version == 0);
            }
            return Config(model: new ConfigModel() { editType = eType, systemType = system, filePath = filePath, files = files, version = version }).OnSucceed();

        }

        #region private
        /// <summary>
        /// 获取所有历史信息
        /// </summary>
        /// <param name="fileid"></param>
        /// <returns></returns>
        private HistoryHitConfig RefreshHistory(Files file, List<FilesVersion> versions)
        {
            HistoryHitConfig config = new HistoryHitConfig();
            config.currentVersion = file.CurrentVersion;
            config.history = new List<HistoryHit>();
            foreach (var item in versions)
            {
                HistoryHit history = new HistoryHit();
                history.key = item.Version == file.CurrentVersion ? file.FileUri.GetHashCode().ToString().GenerateRevisionId() : item.FileKey;
                history.version = item.Version;
                history.changes = JsonSerializer.DeserializeFromString<List<ChangesConfig>>(item.Changes);
                history.serverVersion = item.ServerVersion;
                history.created = history.changes.First().created;
                history.user = history.changes.First().user;
                if (item.Version == 0) history.changes = new List<ChangesConfig>();
                config.history.Add(history);
            }
            return config;
        }
        /// <summary>
        /// 设置文件版本历史
        /// </summary>
        /// <param name="fileid"></param>
        /// <returns></returns>
        private HistoryCurrentVersion SetHistoryData(Files file, List<FilesVersion> versions, long version)
        {
            HistoryCurrentVersion config = new HistoryCurrentVersion();
            FilesVersion currentVersion = versions.FirstOrDefault(v => v.Version == version);
            FilesVersion nextVersion = versions.FirstOrDefault(v => v.Version == (version + 1));
            FilesVersion preVersion = versions.FirstOrDefault(v => v.Version == (version - 1));
            if (currentVersion != null)
            {
                config.key = currentVersion.FileKey;
                config.url = currentVersion.Version == file.CurrentVersion ? string.Concat(filePath.ApiUrl, file.FileUri) : string.Concat(filePath.ApiUrl, nextVersion.PrevUri);
                config.version = currentVersion.Version;
                if (currentVersion.Version > 0)
                {
                    config.changesUrl = string.IsNullOrWhiteSpace(currentVersion.ChangesUrl) ? "" : string.Concat(filePath.ApiUrl, currentVersion.ChangesUrl);
                    config.previous = new PreviousInfo() { url = "", key = "" };
                    if (preVersion != null)
                    {
                        config.previous.key = preVersion.FileKey;
                        config.previous.url = string.Concat(filePath.ApiUrl, preVersion.PrevUri);
                    }
                }
            }
            return config;
        }
        /// <summary>
        /// 获取Body中的值
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public string GetBody(HttpContext context)
        {
            string body = "";
            try
            {
                using (var receiveStream = context.Request.Body)
                using (var readStream = new StreamReader(receiveStream))
                {
                    body = readStream.ReadToEndAsync().Result;
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            return body;
        }
        /// <summary>
        /// 获取配置文件
        /// </summary>
        /// <param name="editType"></param>
        /// <param name="systemType"></param>
        /// <param name="fileid"></param>
        /// <returns></returns>
        private OfficeConfig Config(ConfigModel model)
        {
            OfficeConfig officeConfig = new OfficeConfig();
            officeConfig.type = model.systemType.ToString();
            officeConfig.documentType = FileUtility.GetFileType("." + model.files.Ext).ToString().ToLower();
            officeConfig.width = "100%";
            officeConfig.height = "100%";
            officeConfig.document = GetDocumentConfig(model: model);
            officeConfig.editorConfig = GetEditorConfig(model: model);
            return officeConfig;
        }
        /// <summary>
        /// 配置文档
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private DocumentConfig GetDocumentConfig(ConfigModel model)
        {
            DocumentConfig document = new DocumentConfig();
            document.title = string.Format("{0}.{1}", model.files.CNName, model.files.Ext);
            document.url = string.Concat(model.filePath.ApiUrl, model.files.FileUri);
            document.fileType = model.files.Ext;
            document.key = model.files.FileUri.GetHashCode().ToString().GenerateRevisionId();
            document.info = new Author() { author = Global.IsChinese ? Global.EmpName : Global.EmpEnName, created = model.files.Creatdate.Value.ToString("yyyy/MM/dd HH:mm") };
            document.permissions = GetPermissionsInfo(model: model);
            return document;
        }
        /// <summary>
        /// 获取权限
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private PermissionsInfo GetPermissionsInfo(ConfigModel model)
        {
            PermissionsInfo permissions = new PermissionsInfo();
            permissions.comment = model.editType != EditType.view && model.editType != EditType.fillForms && model.editType != EditType.embedded && model.editType != EditType.blockcontent;
            permissions.download = true;
            permissions.edit = FileUtility.EditedExts.Contains(string.Concat(".", model.files.Ext)) && (model.editType != EditType.edit || model.editType != EditType.filter || model.editType != EditType.blockcontent);
            permissions.fillForms = model.editType != EditType.fillForms;
            permissions.modifyFilter = model.editType != EditType.filter;
            permissions.modifyContentControl = model.editType != EditType.blockcontent;
            permissions.review = model.editType == EditType.edit || model.editType == EditType.review;
            permissions.changeHistory = true;
            return permissions;
        }

        /// <summary>
        /// 获取编辑配置
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public EditorConfig GetEditorConfig(ConfigModel model)
        {
            EditorConfig editor = new EditorConfig();
            editor.mode = FileUtility.EditedExts.Contains(string.Concat(".", model.files.Ext)) && model.editType != EditType.view ? EditType.edit.ToString() : EditType.view.ToString();
            editor.lang = "zh";
            editor.callbackUrl = GetCallbackUrl(file: model.files, path: model.filePath);
            editor.user = new User() { id = Global.EmpId.ToString(), name = Global.IsChinese ? Global.EmpName : Global.EmpEnName };
            editor.embedded = new Embedded() { embedUrl = string.Concat(model.filePath.ApiUrl, model.files.FileUri), saveUrl = string.Concat(model.filePath.ApiUrl, model.files.FileUri), shareUrl = string.Concat(model.filePath.ApiUrl, model.files.FileUri), toolbarDocked = "top" };
            editor.customization = GetCustomizationInfo(model: model);
            editor.logo = new LogoInfo() { image = "", imageEmbedded = "", url = model.filePath.WebUrl };
            return editor;
        }
        /// <summary>
        /// 配置自定义信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public CustomizationInfo GetCustomizationInfo(ConfigModel model)
        {
            CustomizationInfo customizationInfo = new CustomizationInfo();
            customizationInfo.chat = true;
            customizationInfo.help = false;
            customizationInfo.about = true;
            customizationInfo.feedback = new FeedBackInfo() { url = "", visible = false };
            customizationInfo.goback = GetGoBackInfo(model: model);
            customizationInfo.customer = GetCustomerInfo(model: model);
            return customizationInfo;
        }
        /// <summary>
        /// 获取返回信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private GoBackInfo GetGoBackInfo(ConfigModel model)
        {
            GoBackInfo info = new GoBackInfo();
            info.requestClose = true;
            info.blank = true;
            info.url = string.Concat(model.filePath.WebUrl, "/Index");
            return info;
        }
        /// <summary>
        /// 获取自定义关于信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private CustomerInfo GetCustomerInfo(ConfigModel model)
        {
            CustomerInfo info = new CustomerInfo();
            info.address = "四川-成都-青羊-府南新区";
            info.info = "文档管理中心";
            info.www = string.Concat(model.filePath.WebUrl, "/Index");
            return info;
        }
        /// <summary>
        /// 回调地址
        /// </summary>
        /// <param name="file"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public string GetCallbackUrl(Files file, FilePath path)
        { 
            var token = new TokenFile().GenerateToken(Global.TenementCode, Global.EmpId.ToString()).Result;
            if (token is null) return "";
            return string.Concat(path.ApiUrl, $"/api/filetrack/v1.0/track?fileid={file.AutoId}&token={token.access_token}");
        }
        #endregion
    }
}
